
#include <deque>
#include <map>
#include <set>

#include "joystick.h"

#define INPUT_B1		0
#define INPUT_B2		1
#define INPUT_B3		2	
#define INPUT_B4		3
#define INPUT_B5		4
#define INPUT_B6		5
#define INPUT_B7		6
#define INPUT_B8		7
#define INPUT_UP		20
#define INPUT_RIGHT		21
#define INPUT_DOWN		22
#define INPUT_LEFT		23
#define INPUT_ESCAPE	27
#define INPUT_QUIT		28
#define INPUT_OTHER 	29
#define INPUT_LAST      30

#define INPUT_MAX_PLAYERS 5

#define INPUT_PRESSED 	1 
#define INPUT_RELEASED 	0 

struct Inputevent {
	int button;
	int change;
	int player; 
};


struct Inputstate {
	int button;
	int player; 
	Inputstate() 				 { button = INPUT_OTHER; player = 0; 	}
	Inputstate(int pla, int but) { button = but; player = pla; 			}
};


typedef std::deque < Inputevent > Inputlist;
typedef std::set < int >  Inputset;

typedef std::map < int , Inputstate > Inputmap;

struct Input {
	Joysticklist		joysticks;
	Inputlist 			inputlist;
	int					state[INPUT_MAX_PLAYERS][INPUT_LAST];
	int handle_max ;
	Inputmap            map;
	Input(bool openjoysticks = true) { 

		handle_max = 100; 
		if(openjoysticks) { 
			joysticks = Joystick::open_all();
		}

		SDL_EventState(SDL_KEYDOWN, SDL_IGNORE);
		SDL_EventState(SDL_KEYUP, SDL_IGNORE);
		SDL_EventState(SDL_JOYAXISMOTION, SDL_IGNORE);
		SDL_EventState(SDL_JOYBUTTONDOWN, SDL_IGNORE);
		SDL_EventState(SDL_JOYBUTTONUP, SDL_IGNORE);
		// Disable automatic event processing for keyboard and joystick.

		map[SDLK_UP] 		= Inputstate(1, INPUT_UP);
		map[SDLK_DOWN] 		= Inputstate(1, INPUT_DOWN);
		map[SDLK_RIGHT]		= Inputstate(1, INPUT_RIGHT);
		map[SDLK_LEFT]  	= Inputstate(1, INPUT_LEFT);
		map[SDLK_F10] 		= Inputstate(1, INPUT_QUIT);
		map[SDLK_ESCAPE] 	= Inputstate(1, INPUT_ESCAPE);
		map[SDLK_RSHIFT]    = Inputstate(1, INPUT_B1);
		map[SDLK_RCTRL] 	= Inputstate(1, INPUT_B2);
		map[SDLK_RETURN]    = Inputstate(1, INPUT_B3);
		map[SDLK_BACKSPACE] = Inputstate(1, INPUT_B4);
		// map from keyboard to virtual inupts.
		// set the state map to 0.
		for(int i=0; i < INPUT_MAX_PLAYERS; i++) {
		state[i][INPUT_UP] 	= 0;
		state[i][INPUT_DOWN]	= 0;
		state[i][INPUT_RIGHT]	= 0;
		state[i][INPUT_LEFT]	= 0;
		state[i][INPUT_QUIT]	= 0;
		state[i][INPUT_ESCAPE]	= 0;
		state[i][INPUT_B1]	= 0;
		state[i][INPUT_B2]	= 0;
		state[i][INPUT_B3]	= 0;
		state[i][INPUT_B4]	= 0;
		state[i][INPUT_B5]	= 0;
		state[i][INPUT_B6]	= 0;
		state[i][INPUT_B7]	= 0;
		state[i][INPUT_B8]	= 0;
		}
	} 
	int process();
	int handle_events();
	~Input() {
		Joystick::close_all(joysticks);	
	}
	bool is_input(int input, int player = 1) {
		return state[player][input];
	}
	
    bool is_up(int player = 1) 		{	return state[player][INPUT_UP];		}
	bool is_down(int player = 1) 	{	return state[player][INPUT_DOWN];	}
	bool is_left(int player = 1) 	{	return state[player][INPUT_LEFT];	}
	bool is_right (int player = 1)  {	return state[player][INPUT_RIGHT];	}
	bool is_b1 (int player = 1)  	{	return state[player][INPUT_B1];		}
	bool is_b2 (int player = 1)  	{	return state[player][INPUT_B2];		}
	bool is_b3 (int player = 1)  	{	return state[player][INPUT_B3];		}
	bool is_b4(int player = 1)  	{	return state[player][INPUT_B4];		}
	bool is_escape(int player = 1) 	{	return state[player][INPUT_ESCAPE];	}
	bool is_quit(int player = 1)  	{	return state[player][INPUT_QUIT];	}
	
	
	
	
	void state_show(int player = 1) {
		printf("u:%d d:%d r:%d l:%d q:%d e:%d 1:%d 2:%d 3:%d 4:%d 5:%d 6:%d 7:%d 8:%d\n",
		state[player][INPUT_UP],
		state[player][INPUT_DOWN],
		state[player][INPUT_RIGHT], 
		state[player][INPUT_LEFT], 
		state[player][INPUT_QUIT], 
		state[player][INPUT_ESCAPE], 
		state[player][INPUT_B1], 
		state[player][INPUT_B2], 
		state[player][INPUT_B3], 
		state[player][INPUT_B4],
		state[player][INPUT_B5],
		state[player][INPUT_B6],
		state[player][INPUT_B7],
		state[player][INPUT_B8]
		);
	}
};

/*

struct Input {
	Input kind;
	Se < Type >
};

*/
